package com.cloud.common.polyv.util;

import java.io.File;
import java.util.*;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloud.common.polyv.config.SystemUtil;
import com.google.common.collect.Maps;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

/**
 * 保利威视工具类
 * @author Aijm
 * @since 2019/10/6
 */
@Slf4j
@UtilityClass
public final class PolyvUtil {


//	/**
//	 * 获取code
//	 *
//	 * @param polyvCode
//	 * @return
//	 */
//	public static String getPolyvCode(PolyvCode polyvCode) {
//		try {
//			return HttpUtil.encode(
//					Base64.encode(SecureUtil.des(Base64.decode(KEY)).encrypt(JSONUtil.toJSONString(polyvCode))),
//					CHARSET_UTF_8);
//		} catch (Exception e) {
//			log.error("保利威视，加密出错", e);
//			return "";
//		}
//	}

//	/**
//	 * code解密
//	 *
//	 * @param code
//	 * @return
//	 */
//	public static PolyvCode decode(String code) {
//		try {
//			return JSON.parseObject(new String(
//					SecureUtil.des(Base64.decode(KEY)).decrypt(Base64.decode(HttpUtil.decode(code, CHARSET_UTF_8)))),
//					PolyvCode.class);
//		} catch (Exception e) {
//			log.error("保利威视，解密出错", e);
//			return null;
//		}
//	}

    /**
     *  bo 中ip 需要填写 要不然签名有误
     * @param bo
     * @param useid
     * @param secretkey
     * @return
     */
	@SuppressWarnings("unchecked")
	public static PolyvSignResult getSignForH5(PolyvSign bo, String useid, String secretkey) {
		// 根据时间戳、vid、密钥生成sign值
		String ts = String.valueOf(System.currentTimeMillis());

		// 获取播放token
		Map<String, Object> map = Maps.newHashMap();
		map.put("userId", useid);
		map.put("videoId", bo.getVid());
		map.put("ts", ts);
		map.put("viewerIp", bo.getIp());
		map.put("viewerName", bo.getUserNo());
		map.put("extraParams", "HTML5");
		map.put("viewerId", bo.getUserNo());
		String concated = "extraParams" + map.get("extraParams") + "ts" + map.get("ts") + "userId" + map.get("userId")
				+ "videoId" + map.get("videoId") + "viewerId" + map.get("viewerId") + "viewerIp" + map.get("viewerIp")
				+ "viewerName" + map.get("viewerName");
		map.put("sign", SecureUtil.md5(secretkey + concated + secretkey).toUpperCase());
		String result = HttpUtil.post(SystemUtil.POLYV_GETTOKEN, map);
		log.info("保利威视，获取token接口：result={}", result);
		Map<String, Object> resultMap = JSON.parseObject(result, HashMap.class);
		int code = Integer.valueOf(resultMap.get("code").toString()).intValue();
		if (code != 200) {
			return null;
		}
		Map<String, Object> data = (Map<String, Object>) resultMap.get("data");
		if (data == null || data.isEmpty()) {
			return null;
		}
		PolyvSignResult dto = new PolyvSignResult();
		dto.setSign(SecureUtil.md5(secretkey + bo.getVid() + ts));
		dto.setTs(ts);
		dto.setToken(data.get("token").toString());
		return dto;
	}

    /**
     * 获取视频详细信息
     * @param vid
     * @param secretkey
     * @param useid
     * @return
     */
	public static UploadFileResult getVideo(String vid, String secretkey, String useid) {
		Map<String, Object> param = Maps.newTreeMap();
		param.put("vid", vid);
		param.put("format", "json");
        // 当前13位毫秒级时间戳
		param.put("ptime", String.valueOf(System.currentTimeMillis()));
        StringBuilder signStr = getSignStr(param);
        signStr.append(secretkey);
		param.put("sign", SecureUtil.sha1(signStr.toString()).toUpperCase());
		String s = HttpUtil.post("http://api.polyv.net/v2/video/{userid}/get-video-msg".replace("{userid}", useid), param);
		try {
			@SuppressWarnings("unchecked")
			Map<String, Object> m = JSON.parseObject(s, HashMap.class);
			if (m.get("code").toString().equals("200")) {
				// 成功
				return JSON.parseArray(JSON.toJSONString(m.get("data")), UploadFileResult.class).get(0);
			}
			log.error("获取视频失败，原因为：{}", s);
		} catch (Exception e) {
			log.error("获取视频失败异常，结果={}，参数={}", s, param, e);
		}
		return null;
	}

    /**
     * 获取 sign str
     * @param param
     * @return
     */
    private static StringBuilder getSignStr(Map<String, Object> param) {
        StringBuilder signStr = new StringBuilder();
        for (Map.Entry<String, Object> entry : param.entrySet()) {
            signStr.append("&").append(entry.getKey()).append("=").append(entry.getValue());
        }
        signStr = signStr.deleteCharAt(0);
        return signStr;
    }

    /**
	 * 上传视频 http://dev.polyv.net/2014/videoproduct/v-api/v-api-upload/uploadfile/
	 *
	 * @param file
	 * @return
	 */
	public static UploadFileResult uploadFile(File file, UploadFile uploadFile, String writetoken) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("writetoken", writetoken);
		param.put("JSONRPC", "{\"title\": \"" + uploadFile.getTitle() + "\", \"tag\": \"" + uploadFile.getTag()
				+ "\", \"desc\": \"" + uploadFile.getDesc() + "\"}");
		param.put("cataid", uploadFile.getCataid());
		if (StrUtil.isNotBlank(uploadFile.getWatermark())) {
			param.put("watermark", uploadFile.getWatermark());
		}
		param.put("Filedata", file);
		String result = HttpUtil.post(SystemUtil.POLYV_UPLOADVIDEO, param, 10000000);
		try {
			JSONObject json = JSONObject.parseObject(result);
			if ("0".equals(json.getString("error"))) {
				return JSON.parseArray(json.getString("data"), UploadFileResult.class).get(0);
			}
		} catch (Exception e) {
			log.error(e.toString(), e);
		}
		log.error("保利威视，上传视频失败，原因={}", result);
		return null;
	}

	/**
	 * 删除视频
	 */
	public static String deleteFile(String vid, String useid, String secretkey) {
		Map<String, Object> paramMap = Maps.newTreeMap();
		// 用户ID
		paramMap.put("userid", useid);
        // 视频ID
		paramMap.put("vid", vid);
        // 当前13位毫秒级时间戳
		paramMap.put("ptime", String.valueOf(System.currentTimeMillis()));
        StringBuilder signStr = getSignStr(paramMap);
        signStr.append(secretkey);
		String sign = SecureUtil.sha1(signStr.toString()).toUpperCase();
		paramMap.put("sign", sign);

		String url = SystemUtil.POLYV_DELETEVIDEO.replace("{userid}", useid);
		return HttpUtil.post(url, paramMap);
	}


	/**
	 * 上传问题接口
	 */
	public static QuestionResult uploadQuestion(Question question, String writetoken) {
		try {
			String url = SystemUtil.POLYV_QUESTION;
			JSONArray choices = new JSONArray();
			for (String value : question.getAnswerList()) {
				JSONObject answer = new JSONObject();
				answer.put("answer", value);
				choices.add(answer);
			}
			JSONObject righeAnswer = new JSONObject();
			righeAnswer.put("answer", question.getRightAnswer());
			righeAnswer.put("right_answer", question.getRight());
			choices.add(righeAnswer);
			Map nvps = Maps.newHashMap();
			nvps.put("method", "saveExam");
			nvps.put("writetoken", writetoken);
			nvps.put("vid", question.getVid());
			nvps.put("examId", question.getExamId());
			nvps.put("seconds", String.valueOf(question.getSeconds()));
			nvps.put("question", question.getQues());
			nvps.put("choices", choices.toString());
			nvps.put("skip", String.valueOf(question.isSkip()));
			nvps.put("answer", question.getAnswer());
			nvps.put("wrongShow", String.valueOf(question.getWrongShow()));
			nvps.put("wrongTime", String.valueOf(question.getWrongTime()));

			String json = HttpUtil.post(url, nvps);
			return JSONUtil.toBean(json, QuestionResult.class);
		} catch (Exception e) {
			log.error("添加问题失败", e);
		}
		return null;
	}


	/**
	 * 保利威视，视频上传回调接口
	 *
	 * @param polyvVideo
	 * @return
	 * @author wuyun
	 */
	public static String video(PolyvVideo polyvVideo) {
		if (checkSign(polyvVideo.getSign(), polyvVideo.getType(), polyvVideo.getVid(), polyvVideo.getSecretkey())) {
			if ("pass".equalsIgnoreCase(polyvVideo.getType())) {
				log.warn("保利威视-上传视频-回调成功：{}", polyvVideo);
				return "success";
			}
		}
		return "fail";
	}

	/**
	 * sign值校验
	 * @param sign
	 * @param type
	 * @param vid
	 * @param secretkey
	 * @return
	 */
	public static boolean checkSign(String sign, String type, String vid, String secretkey) {
		StringBuilder sb = new StringBuilder();
		// manage 为借口参数固定值
		String argSign = SecureUtil.md5(sb.append("manage").append(type).append(vid).append(secretkey).toString());
		if (argSign.equals(sign)) {
			return true;
		}
		return false;
	}

	/**
	 * 获取sign
	 *
	 * @param paramMap
	 * @return
	 */
	public static String getSign(Map<String, Object> paramMap, String secretkey) {
		if (paramMap.isEmpty()) {
			return "";
		}
		SortedMap<String, Object> smap = new TreeMap<String, Object>(paramMap);
		StringBuilder sbr = new StringBuilder();
		for (Map.Entry<String, Object> m : smap.entrySet()) {
			String value = String.valueOf(m.getValue());
			if (StrUtil.isNotBlank(value)) {
				sbr.append(m.getKey()).append("=").append(value).append("&");
			}
		}
		sbr.delete(sbr.length() - 1, sbr.length());
		String argPreSign = sbr.append("&paySecret=").append(secretkey).toString();
		return SecureUtil.md5(argPreSign).toUpperCase();
	}

}
